// Copyright  2012 Petr TALLA. [petr.talla@gmail.com]
// This file is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;  without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
// [http://www.gnu.org/copyleft/lesser.html]
//=============================================================================

package tc.common.symbology;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Vector;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;

public class Style {
	public Vector<Sfeat> sfeats = new Vector<Sfeat>();
	public String id; 
	
	public Style (String id) {
		this.id = new String(id);
	}
	
	public void drawLine(Graphics g, Point p0, Point p1) {
		Color oldColor = g.getColor();
		g.setColor(Color.BLACK);
		
		for (int i = 0; i < sfeats.size(); i++ ) {
			Sfeat sfeat = sfeats.get(i);
			if (sfeat.getAsLine()!=null) {
				SfeatLine sfLine = sfeat.getAsLine();
				
				if (sfLine.symbolBegin != null) {
					sfLine.symbolBegin.display(g, p0.x, p0.y, Symbol.DIM*2/16, Symbol.DIM*2/16);
				}
				
				if (sfLine.symbolEnd != null) {
					sfLine.symbolEnd.display(g, p1.x, p1.y, Symbol.DIM*2/16, Symbol.DIM*2/16);
				}

			}
		}
		
		g.drawLine(p0.x, p0.y, p1.x, p1.y);
		
		g.setColor(oldColor);
	}
	
	public void drawRect(Graphics g, int x, int y, int width, int height, int offset) {
		Color oldColor = g.getColor();
		
		for (int i = 0; i < sfeats.size(); i++ ) {
			Sfeat sfeat = sfeats.get(i);
			if (sfeat.getAsLine()!=null) {
				SfeatLine sfLine = sfeat.getAsLine();
				g.setColor(sfLine.color);
				int off = (int)(sfLine.offset*4.0) + offset;
				g.drawRect(x - off, y - off, width + 2*off, height + 2*off);
			}
			else if (sfeat.getAsArea()!=null) {
				SfeatArea sfArea = sfeat.getAsArea();
				g.setColor(sfArea.color);
				int off = (int)(sfArea.offset*4.0) + offset;
				g.fillRect(x - off, y - off, width + 2*off, height + 2*off);
			}
		}
		
		g.setColor(oldColor);
	}
	
	public double solidOffset() {
		double result = 0;
		
		for (int i = 0; i < sfeats.size(); i++ ) {
			SfeatArea sf = sfeats.get(i).getAsArea();
			if (sf == null) continue;
			if (sf.offset <= result) continue;
			sf.offset = result;
		}
		
		return result;
	}
	
	public void drawIcon(Graphics g, int x, int y, int width, int height) {
		boolean drawn = false;
		
		for (int i = 0; i < sfeats.size(); i++ ) {
			SfeatSymbol sfSymbol = sfeats.get(i).getAsSymbol();
			if (sfSymbol == null) continue;
			sfSymbol.symbol.display(g, x+width/2, y+width/2, Symbol.DIM*2/width, Symbol.DIM*2/height);
			drawn = true;
		}
		
		if (drawn) return;
		
		drawRect(g, x, y, width, height, 0);
	}
	
	public void save(ObjectNode jsonStyle, ObjectMapper mapper) {
		jsonStyle.put("id", id);
		
		ArrayNode jsonSfeats = mapper.createArrayNode();
		jsonStyle.put("sfeats", jsonSfeats);
		
		for ( int i = 0; i < sfeats.size(); i++ ) {
			Sfeat sfeat = sfeats.get(i);
			
			ObjectNode  jsonSfeat  = mapper.createObjectNode();
			jsonSfeats.add(jsonSfeat);
			
			if (sfeat.getAsArea() != null) {
				SfeatArea sfArea = sfeat.getAsArea();
				jsonSfeat.put("type",  "AREA");
				jsonSfeat.put("red",   sfArea.color.getRed());
				jsonSfeat.put("green", sfArea.color.getGreen());
				jsonSfeat.put("blue",  sfArea.color.getBlue());
				jsonSfeat.put("offset",  sfArea.offset);
			}
			else if (sfeat.getAsLine() != null) {
				SfeatLine sfLine = sfeat.getAsLine();
				jsonSfeat.put("type",  "LINE");
				jsonSfeat.put("red",   sfLine.color.getRed());
				jsonSfeat.put("green", sfLine.color.getGreen());
				jsonSfeat.put("blue",  sfLine.color.getBlue());
				jsonSfeat.put("offset",  sfLine.offset);
				if (sfLine.symbolBegin != null) jsonSfeat.put("symbol_begin", sfLine.symbolBegin.id);
				if (sfLine.symbolEnd   != null) jsonSfeat.put("symbol_end", sfLine.symbolEnd.id);
			}
			else if (sfeat.getAsSymbol() != null) {
				SfeatSymbol sfSymbol = sfeat.getAsSymbol();
				jsonSfeat.put("type",  "SYMBOL");
				jsonSfeat.put("symbol",  sfSymbol.symbol.id);
			}
		}	
	}
	
	public double shapeOffset() {
		double offset = 0.0;
		
		for ( int i = 0; i < sfeats.size(); i++ ) {
			Sfeat sfeat = sfeats.get(i);
			
			if (sfeat.getAsArea() != null) {
				SfeatArea sfArea = sfeat.getAsArea();
				if (sfArea.offset > offset) offset = sfArea.offset;
			}
			else if (sfeat.getAsLine() != null) {
				SfeatLine sfLine = sfeat.getAsLine();
				if (sfLine.offset > offset) offset = sfLine.offset;				
			}
		} 
		
		return offset;
	}
}
